30.05.2017

TO DO:

06.06.2017

tidyCL<-read.csv("tortoises_tidy.csv", sep=";", header=TRUE)


colnames(tidyCL)[6] <- "MAmin"
colnames(tidyCL)[7] <- "Mamax"
colnames(tidyCL)[17] <- "CL"
colnames(tidyCL)[18] <- "PL"


statsCL <- tidyCL %>%
  dplyr::filter(!is.na(CL)) %>%
  summarise(min = min(CL), max = max(CL), var(CL), mean= mean(CL), median= median(CL))#, skew(CL), kurtosi(CL)) n = n(), 



Map <- tidyCL %>%
  dplyr::select(Genus, Taxon, Latitude, Longitude, Country, CL, PL) %>%
  group_by(Latitude) %>%
  mutate(count= n())

mapWorld <- borders("world", colour="azure3", fill="azure3") # create a layer of borders


mp <- Map %>%
  ggplot(aes(Longitude, Latitude)) + mapWorld +
#  geom_point(fill="red", colour="red", size=0.5) +
  geom_point(aes(Longitude, Latitude,colour=CL, size=count))

mp


library(plotly)


ggplotly(mp)

Get an overview over body size data

tidyCL <-  tidyCL %>%
  mutate(Age= (MAmin+Mamax)/2)

hist(tidyCL$CL)
hist(tidyCL$Age)

TO DO:

  • map localities with differing colors for: CL available, CL extrapolated (from PL or figures), CL missing
  • complete data set!
  • get missing refences/make list of missing references

08.06.17

Map all localities with sample size and age indicated (regardless of whether CL information is available):

test<-read.csv("tortoises13-04.csv", sep=";", header=TRUE)

colnames(test)[6] <- "Mamin"
colnames(test)[7] <- "Mamax"

Test <- test %>%
  dplyr::select(Locality, Country, Latitude, Longitude, Mamin, Mamax, Epoch, Genus, Species, Taxon, CL) %>%
  mutate(Age= (Mamin+Mamax)/2) %>%   # create mean age
  group_by(Latitude) %>%
  mutate(count= n())

#mapWorld <- borders("world", colour="azure3", fill="azure3") # create a layer of borders  
  
map <- Test %>%
  ggplot(aes(Longitude, Latitude)) + mapWorld +
  #geom_point(fill="red", colour="red", size=0.5) +
  geom_point(aes(Longitude, Latitude,colour=Age, size=count))

map

ggplotly(map)

TO DO:

  • get general statistical overview over data (stru, normal distribution?, mean/mode/median/min/max, hist plot etc. –> see Catalina’s paper)

Try paleoTS with some first real data. Here is the underlying data:

tidyCL

Prepare data for conversion to paleoTS-object:


SampleSize <- tidyCL %>%
  dplyr::select(MAmin, Mamax, CL) %>%
  filter(CL != "NA")

length(SampleSize$CL)


TidyCL <- tidyCL %>%
  dplyr::select(MAmin, Mamax, CL) %>%
  dplyr::filter(CL != "NA") %>%
  mutate(tt= (MAmin+Mamax)/2) %>% # create mean age
  group_by(tt) %>% #create time bins
  summarise(mm=mean(CL), vv=var(CL), nn=n()) #create means etc. for each time bin 

TidyCL[is.na(TidyCL)]<-0 #subset NAs with O for 

TidyCL



bins <- tidyCL %>%
#  select(MAmin, Mamax, CL) %>%
  filter(CL != "NA") %>%
  mutate(tt= (MAmin+Mamax)/2) %>% # create mean age
  group_by(tt)

bins
library(paleoTS)
paleoTidyCL <-as.paleoTS(TidyCL$mm, TidyCL$vv, TidyCL$nn, TidyCL$tt, MM = NULL, genpars = NULL, label = "Testudinidae body size evolution mode")
paleoTidyCL
plot(paleoTidyCL)

fit3models(paleoTidyCL, silent=FALSE, method="AD", pool=FALSE)   #not working with Test1, because no variances/sample sizes available, I guess

15.06.2017

Use paleoTS with data from the past 10 Mya (today - Pliocene, beginning of Miocene)

unique(tidyCL$Epoch)

PleiPlioCL <- tidyCL %>%
  filter(Age < 10.000)

length(PleiPlioCL$CL)

PPCL <- PleiPlioCL %>%
  select(MAmin, Mamax, CL) %>%
  filter(CL != "NA") %>%
  mutate(tt= (MAmin+Mamax)/2) %>% # create mean age
  group_by(tt) %>% #create time bins
  summarise(mm=mean(CL), vv=var(CL), nn=n()) #create means etc. for each time bin 

PPCL[is.na(PPCL)]<-0 #subset NAs with O for 

PPCL

bins <- PleiPlioCL %>%
  #  select(MAmin, Mamax, CL) %>%
  filter(CL != "NA") %>%
  mutate(tt= (MAmin+Mamax)/2) %>% # create mean age
  group_by(tt)

bins


paleoPPCL <-as.paleoTS(PPCL$mm, PPCL$vv, PPCL$nn, PPCL$tt, MM = NULL, genpars = NULL, label = "Testudinidae body size evolution mode")
paleoPPCL
plot(paleoPPCL)

fit3models(paleoPPCL, silent=FALSE, method="AD", pool=FALSE)   #not working with Test1, because no variances/sample sizes available, I guess##### play around with speciesgeocodeR 07.06.17 #######
PPmap <- PleiPlioCL %>%
  select(Genus, Taxon, Latitude, Longitude, Country, CL, PL, Age) %>%
  group_by(Latitude) %>%
  mutate(count= n()) %>%
  ggplot(aes(Longitude, Latitude)) + mapWorld +
  geom_point(aes(Longitude, Latitude,colour=Age, size=count))
PPmap
ggplotly(PPmap)
We recommend that you use the dev version of ggplot2 with `ggplotly()`
Install it with: `devtools::install_github('hadley/ggplot2')`

TO DO:

  • finish data set

This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

LS0tDQp0aXRsZTogIkJvZHkgc2l6ZSB0cmVuZHMgaW4gTmVvZ2VuZSB0b3J0b2lzZXMiDQpvdXRwdXQ6DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCmFsd2F5c19hbGxvd19odG1sOiB5ZXMNCi0tLQ0KDQpgYGB7ciAic2V0dXAiLCBpbmNsdWRlPUZBTFNFfQ0KcmVxdWlyZSgia25pdHIiKQ0Kb3B0c19rbml0JHNldChyb290LmRpciA9ICIvL25hdHVya3VuZGVtdXNldW0tYmVybGluLmRlL011c2V1bURGU1Jvb3QvQmVudXR6ZXIvSnVsaWEuSm9vcy9FaWdlbmUgRGF0ZWllbi9NQSIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCiMgMzAuMDUuMjAxNw0KDQojIyBUTyBETzoNClxiZWdpbntpdGVtaXplfQ0KXGl0ZW0gZmlndXJlIG91dCBpZiBDaGVja2xpc3QgZGF0YSBpcyBvZiBhbnkgdXNlIChtZWFucz8gbWVkaWFucz8gc2FtcGxlIHNpemU/KSBvciBzZWUgaWYgYXV0aG9ycyBjYW4gcHJvdmlkZSBuZWNlc3NhcnkgZGF0YQ0KXGl0ZW0gZG8gcGFsZW9UUyBhbmFseXNlcyB3aXRoIEZGQiBkYXRhIHNldA0KXGl0ZW0gcmVhZCBIdW50IHBhcGVycyAoc2VlIGNpdGF0aW9ucyBpbiBDYXRhbGluYSdzIHBhcGVyIDIwMDYsIDIwMDgsIDIwMDgsIDIwMTA7IGFsc28gMjAxNSkNClxpdGVtIGZpZ3VyZSBvdXQgaG93IHRvIGltcGxlbWVudCBwaHlsb2dlbnkuLi4gd2VsbCwgZmlndXJlIG91dCBob3cgdG8gZG8gcGFsZW9UUyBhbmFseXNlcyB3aXRoIG1vcmUgdGhhbiBvbmUgdGF4b24gd2l0aG91dCBwb29saW5nIGV2ZXJ5dGhpbmcgdG9nZXRoZXIgKGFzIGluIFRlc3QyKQ0KXGVuZHtpdGVtaXplfQ0KDQoNCiMgMDYuMDYuMjAxNw0KYGBge3IgIk1hcCBmb3NzaWwgcmVjb3JkcyB3aXRoIENMIGluZm9ybWF0aW9uIGF2YWlsYWJsZSJ9DQp0aWR5Q0w8LXJlYWQuY3N2KCJ0b3J0b2lzZXNfdGlkeS5jc3YiLCBzZXA9IjsiLCBoZWFkZXI9VFJVRSkNCg0KDQpjb2xuYW1lcyh0aWR5Q0wpWzZdIDwtICJNQW1pbiINCmNvbG5hbWVzKHRpZHlDTClbN10gPC0gIk1hbWF4Ig0KY29sbmFtZXModGlkeUNMKVsxN10gPC0gIkNMIg0KY29sbmFtZXModGlkeUNMKVsxOF0gPC0gIlBMIg0KDQoNCnN0YXRzQ0wgPC0gdGlkeUNMICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShDTCkpICU+JQ0KICBzdW1tYXJpc2UobWluID0gbWluKENMKSwgbWF4ID0gbWF4KENMKSwgdmFyKENMKSwgbWVhbj0gbWVhbihDTCksIG1lZGlhbj0gbWVkaWFuKENMKSkjLCBza2V3KENMKSwga3VydG9zaShDTCkpIG4gPSBuKCksIA0KDQoNCg0KTWFwIDwtIHRpZHlDTCAlPiUNCiAgZHBseXI6OnNlbGVjdChHZW51cywgVGF4b24sIExhdGl0dWRlLCBMb25naXR1ZGUsIENvdW50cnksIENMLCBQTCkgJT4lDQogIGdyb3VwX2J5KExhdGl0dWRlKSAlPiUNCiAgbXV0YXRlKGNvdW50PSBuKCkpDQoNCm1hcFdvcmxkIDwtIGJvcmRlcnMoIndvcmxkIiwgY29sb3VyPSJhenVyZTMiLCBmaWxsPSJhenVyZTMiKSAjIGNyZWF0ZSBhIGxheWVyIG9mIGJvcmRlcnMNCg0KDQptcCA8LSBNYXAgJT4lDQogIGdncGxvdChhZXMoTG9uZ2l0dWRlLCBMYXRpdHVkZSkpICsgbWFwV29ybGQgKw0KIyAgZ2VvbV9wb2ludChmaWxsPSJyZWQiLCBjb2xvdXI9InJlZCIsIHNpemU9MC41KSArDQogIGdlb21fcG9pbnQoYWVzKExvbmdpdHVkZSwgTGF0aXR1ZGUsY29sb3VyPUNMLCBzaXplPWNvdW50KSkNCg0KbXANCg0KDQpsaWJyYXJ5KHBsb3RseSkNCg0KDQpnZ3Bsb3RseShtcCkNCg0KYGBgDQoNCkdldCBhbiBvdmVydmlldyBvdmVyIGJvZHkgc2l6ZSBkYXRhDQoNCmBgYHtyICJEYXRhIHN0cnVjdHVyZSJ9DQp0aWR5Q0wgPC0gIHRpZHlDTCAlPiUNCiAgbXV0YXRlKEFnZT0gKE1BbWluK01hbWF4KS8yKQ0KDQpoaXN0KHRpZHlDTCRDTCkNCmhpc3QodGlkeUNMJEFnZSkNCg0KYGBgDQoNCg0KIyMgVE8gRE86DQoqIG1hcCBsb2NhbGl0aWVzIHdpdGggZGlmZmVyaW5nIGNvbG9ycyBmb3I6IENMIGF2YWlsYWJsZSwgQ0wgZXh0cmFwb2xhdGVkIChmcm9tIFBMIG9yIGZpZ3VyZXMpLCBDTCBtaXNzaW5nDQoqIGNvbXBsZXRlIGRhdGEgc2V0ISANCiAgKyBnZXQgbWlzc2luZyByZWZlbmNlcy9tYWtlIGxpc3Qgb2YgbWlzc2luZyByZWZlcmVuY2VzDQoNCg0KIyAwOC4wNi4xNw0KDQpNYXAgYWxsIGxvY2FsaXRpZXMgd2l0aCBzYW1wbGUgc2l6ZSBhbmQgYWdlIGluZGljYXRlZCAocmVnYXJkbGVzcyBvZiB3aGV0aGVyIENMIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZSk6DQpgYGB7ciAiTWFwIGFsbCByZWNvcmRzIGluZGljYXRpbmcgYWdlIGFuZCBzYW1wbGUgc2l6ZSwgZGlzcmVnYXJkaW5nIGF2YWlsYWJpbGl0eSBvZiBDTCJ9DQp0ZXN0PC1yZWFkLmNzdigidG9ydG9pc2VzMTMtMDQuY3N2Iiwgc2VwPSI7IiwgaGVhZGVyPVRSVUUpDQoNCmNvbG5hbWVzKHRlc3QpWzZdIDwtICJNYW1pbiINCmNvbG5hbWVzKHRlc3QpWzddIDwtICJNYW1heCINCg0KVGVzdCA8LSB0ZXN0ICU+JQ0KICBkcGx5cjo6c2VsZWN0KExvY2FsaXR5LCBDb3VudHJ5LCBMYXRpdHVkZSwgTG9uZ2l0dWRlLCBNYW1pbiwgTWFtYXgsIEVwb2NoLCBHZW51cywgU3BlY2llcywgVGF4b24sIENMKSAlPiUNCiAgbXV0YXRlKEFnZT0gKE1hbWluK01hbWF4KS8yKSAlPiUgICAjIGNyZWF0ZSBtZWFuIGFnZQ0KICBncm91cF9ieShMYXRpdHVkZSkgJT4lDQogIG11dGF0ZShjb3VudD0gbigpKQ0KDQojbWFwV29ybGQgPC0gYm9yZGVycygid29ybGQiLCBjb2xvdXI9ImF6dXJlMyIsIGZpbGw9ImF6dXJlMyIpICMgY3JlYXRlIGEgbGF5ZXIgb2YgYm9yZGVycyAgDQogIA0KbWFwIDwtIFRlc3QgJT4lDQogIGdncGxvdChhZXMoTG9uZ2l0dWRlLCBMYXRpdHVkZSkpICsgbWFwV29ybGQgKw0KICAjZ2VvbV9wb2ludChmaWxsPSJyZWQiLCBjb2xvdXI9InJlZCIsIHNpemU9MC41KSArDQogIGdlb21fcG9pbnQoYWVzKExvbmdpdHVkZSwgTGF0aXR1ZGUsY29sb3VyPUFnZSwgc2l6ZT1jb3VudCkpDQoNCm1hcA0KDQpnZ3Bsb3RseShtYXApDQpgYGANCg0KIyMgVE8gRE86DQoqIGdldCBnZW5lcmFsIHN0YXRpc3RpY2FsIG92ZXJ2aWV3IG92ZXIgZGF0YSAoc3RydSwgbm9ybWFsIGRpc3RyaWJ1dGlvbj8sIG1lYW4vbW9kZS9tZWRpYW4vbWluL21heCwgaGlzdCBwbG90IGV0Yy4gLS0+IHNlZSBDYXRhbGluYSdzIHBhcGVyKQ0KDQoNCg0KVHJ5IHBhbGVvVFMgd2l0aCBzb21lIGZpcnN0IHJlYWwgZGF0YS4NCkhlcmUgaXMgdGhlIHVuZGVybHlpbmcgZGF0YToNCg0KYGBge3IgIkdldCBhY3R1YWwgZGF0YSJ9DQp0aWR5Q0wNCg0KYGBgDQoNClByZXBhcmUgZGF0YSBmb3IgY29udmVyc2lvbiB0byBwYWxlb1RTLW9iamVjdDoNCg0KYGBge3IgIkRhdGEgcHJlcGFyYXRpb24gZm9yIGFuYWx5c2VzIHdpdGggcGFsZW9UUyJ9DQoNClNhbXBsZVNpemUgPC0gdGlkeUNMICU+JQ0KICBkcGx5cjo6c2VsZWN0KE1BbWluLCBNYW1heCwgQ0wpICU+JQ0KICBmaWx0ZXIoQ0wgIT0gIk5BIikNCg0KbGVuZ3RoKFNhbXBsZVNpemUkQ0wpDQoNCg0KVGlkeUNMIDwtIHRpZHlDTCAlPiUNCiAgZHBseXI6OnNlbGVjdChNQW1pbiwgTWFtYXgsIENMKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDTCAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKHR0PSAoTUFtaW4rTWFtYXgpLzIpICU+JSAjIGNyZWF0ZSBtZWFuIGFnZQ0KICBncm91cF9ieSh0dCkgJT4lICNjcmVhdGUgdGltZSBiaW5zDQogIHN1bW1hcmlzZShtbT1tZWFuKENMKSwgdnY9dmFyKENMKSwgbm49bigpKSAjY3JlYXRlIG1lYW5zIGV0Yy4gZm9yIGVhY2ggdGltZSBiaW4gDQoNClRpZHlDTFtpcy5uYShUaWR5Q0wpXTwtMCAjc3Vic2V0IE5BcyB3aXRoIE8gZm9yIA0KDQpUaWR5Q0wNCg0KDQoNCmJpbnMgPC0gdGlkeUNMICU+JQ0KIyAgc2VsZWN0KE1BbWluLCBNYW1heCwgQ0wpICU+JQ0KICBmaWx0ZXIoQ0wgIT0gIk5BIikgJT4lDQogIG11dGF0ZSh0dD0gKE1BbWluK01hbWF4KS8yKSAlPiUgIyBjcmVhdGUgbWVhbiBhZ2UNCiAgZ3JvdXBfYnkodHQpDQoNCmJpbnMNCg0KYGBgDQoNCg0KDQpgYGB7ciAiVHJ5IHBhbGVvVFMgd2l0aCBhY3R1YWwgZGF0YSJ9DQpsaWJyYXJ5KHBhbGVvVFMpDQpwYWxlb1RpZHlDTCA8LWFzLnBhbGVvVFMoVGlkeUNMJG1tLCBUaWR5Q0wkdnYsIFRpZHlDTCRubiwgVGlkeUNMJHR0LCBNTSA9IE5VTEwsIGdlbnBhcnMgPSBOVUxMLCBsYWJlbCA9ICJUZXN0dWRpbmlkYWUgYm9keSBzaXplIGV2b2x1dGlvbiBtb2RlIikNCnBhbGVvVGlkeUNMDQpwbG90KHBhbGVvVGlkeUNMKQ0KDQpmaXQzbW9kZWxzKHBhbGVvVGlkeUNMLCBzaWxlbnQ9RkFMU0UsIG1ldGhvZD0iQUQiLCBwb29sPUZBTFNFKSAgICNub3Qgd29ya2luZyB3aXRoIFRlc3QxLCBiZWNhdXNlIG5vIHZhcmlhbmNlcy9zYW1wbGUgc2l6ZXMgYXZhaWxhYmxlLCBJIGd1ZXNzDQoNCmBgYA0KDQoNCiMxNS4wNi4yMDE3DQoNClVzZSBwYWxlb1RTIHdpdGggZGF0YSBmcm9tIHRoZSBwYXN0IDEwIE15YSAodG9kYXkgLSBQbGlvY2VuZSwgYmVnaW5uaW5nIG9mIE1pb2NlbmUpDQoNCmBgYHtyICJCb2R5IHNpemUgdHJlbmRzIGZyb20gUGxpb2NlbmUvTWlvY2VuZSB1bnRpbCB0b2RheSJ9DQp1bmlxdWUodGlkeUNMJEVwb2NoKQ0KDQpQbGVpUGxpb0NMIDwtIHRpZHlDTCAlPiUNCiAgZmlsdGVyKEFnZSA8IDEwLjAwMCkNCg0KbGVuZ3RoKFBsZWlQbGlvQ0wkQ0wpDQoNClBQQ0wgPC0gUGxlaVBsaW9DTCAlPiUNCiAgc2VsZWN0KE1BbWluLCBNYW1heCwgQ0wpICU+JQ0KICBmaWx0ZXIoQ0wgIT0gIk5BIikgJT4lDQogIG11dGF0ZSh0dD0gKE1BbWluK01hbWF4KS8yKSAlPiUgIyBjcmVhdGUgbWVhbiBhZ2UNCiAgZ3JvdXBfYnkodHQpICU+JSAjY3JlYXRlIHRpbWUgYmlucw0KICBzdW1tYXJpc2UobW09bWVhbihDTCksIHZ2PXZhcihDTCksIG5uPW4oKSkgI2NyZWF0ZSBtZWFucyBldGMuIGZvciBlYWNoIHRpbWUgYmluIA0KDQpQUENMW2lzLm5hKFBQQ0wpXTwtMCAjc3Vic2V0IE5BcyB3aXRoIE8gZm9yIA0KDQpQUENMDQoNCmJpbnMgPC0gUGxlaVBsaW9DTCAlPiUNCiAgIyAgc2VsZWN0KE1BbWluLCBNYW1heCwgQ0wpICU+JQ0KICBmaWx0ZXIoQ0wgIT0gIk5BIikgJT4lDQogIG11dGF0ZSh0dD0gKE1BbWluK01hbWF4KS8yKSAlPiUgIyBjcmVhdGUgbWVhbiBhZ2UNCiAgZ3JvdXBfYnkodHQpDQoNCmJpbnMNCg0KDQpwYWxlb1BQQ0wgPC1hcy5wYWxlb1RTKFBQQ0wkbW0sIFBQQ0wkdnYsIFBQQ0wkbm4sIFBQQ0wkdHQsIE1NID0gTlVMTCwgZ2VucGFycyA9IE5VTEwsIGxhYmVsID0gIlRlc3R1ZGluaWRhZSBib2R5IHNpemUgZXZvbHV0aW9uIG1vZGUiKQ0KcGFsZW9QUENMDQpwbG90KHBhbGVvUFBDTCkNCg0KZml0M21vZGVscyhwYWxlb1BQQ0wsIHNpbGVudD1GQUxTRSwgbWV0aG9kPSJBRCIsIHBvb2w9RkFMU0UpICAgI25vdCB3b3JraW5nIHdpdGggVGVzdDEsIGJlY2F1c2Ugbm8gdmFyaWFuY2VzL3NhbXBsZSBzaXplcyBhdmFpbGFibGUsIEkgZ3Vlc3MjIyMjIyBwbGF5IGFyb3VuZCB3aXRoIHNwZWNpZXNnZW9jb2RlUiAwNy4wNi4xNyAjIyMjIyMjDQoNCmBgYA0KDQoNCmBgYHtyfQ0KUFBtYXAgPC0gUGxlaVBsaW9DTCAlPiUNCiAgc2VsZWN0KEdlbnVzLCBUYXhvbiwgTGF0aXR1ZGUsIExvbmdpdHVkZSwgQ291bnRyeSwgQ0wsIFBMLCBBZ2UpICU+JQ0KICBncm91cF9ieShMYXRpdHVkZSkgJT4lDQogIG11dGF0ZShjb3VudD0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyhMb25naXR1ZGUsIExhdGl0dWRlKSkgKyBtYXBXb3JsZCArDQogIGdlb21fcG9pbnQoYWVzKExvbmdpdHVkZSwgTGF0aXR1ZGUsY29sb3VyPUFnZSwgc2l6ZT1jb3VudCkpDQoNClBQbWFwDQoNCmdncGxvdGx5KFBQbWFwKQ0KYGBgDQoNCiMjIFRPIERPOiANCiogZmluaXNoIGRhdGEgc2V0DQoqIA0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIA0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIA0KDQpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouDQoNCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLg0K